#ifndef __FIFO_HPP__
#define __FIFO_HPP__

#include <iostream>
#include <string>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cassert>
#include <unistd.h>

using namespace std;

#define Mode 0666
#define Path "./fifo"

class Fifo
{
public:
	Fifo(const string &path = Path) : _path(path)
	{
		umask(0);
		int n = mkfifo(_path.c_str(), Mode); // 创建命名管道，成功返回0，失败返回-1
		if (n == 0)
		{
			cout << "mkfifo success..." << endl;
		}
		else
		{
			cerr << "mkfifo failed, errno: " << errno << ", errstring: " << strerror(errno) << endl;
		}
	}
	~Fifo()
	{
		int n = unlink(_path.c_str());

		if (n == 0)
		{
			cout << "unlink success..." << endl;
		}
		else
		{
			cerr << "unlink failed, errno: " << errno << ", errstring: " << strerror(errno) << endl;
		}
	}

private:
	string _path; // 文件路劲+文件名
};

class Sysn
{
public:
	Sysn(int rfd = -1, int wfd = -1) : _rfd(rfd), _wfd(wfd)
	{
	}
	~Sysn()
	{
	}

	void OpenReadOrDie()
	{
		_rfd = open(Path, O_RDONLY);
		if (_rfd < 0)
		{
			cerr << "oper r error" << endl;
			exit(1);
		}
	}

	void OpenWriteOrDie()
	{
		_wfd = open(Path, O_WRONLY);
		if (_wfd < 0)
		{
			cerr << "oper w error" << endl;
			exit(1);
		}
	}

	bool Wait()
	{
		bool ret = true;
		uint32_t c = 0;
		ssize_t n = read(_rfd, &c, sizeof(uint32_t));
		if (n == sizeof(uint32_t))
		{
			cout << "server wakeup,begin read shm..." << endl;
		}
		else if (n == 0)
		{
			ret = false;
		}
		else
		{
			return false;
		}

		return ret;
	}

	void WakeUp()
	{
		uint32_t c = 0;
		ssize_t n = write(_wfd, &c, sizeof(c));
		assert(n == sizeof(uint32_t));

		cout << "WakeUp Server..." << endl;
	}

private:
	int _rfd;
	int _wfd;
};

#endif